#pragma once
#include "log.hpp"

#include <string>
#include <random>
#include <sstream>
#include <iostream>
#include <atomic>
#include <iomanip>
#include <fstream>
#include <cstring> //for strerror
//16字节
std::string uuid() {
    //前12字节依靠6个0~255的随机数，每个随机数转为两个16进制字符
    std::random_device rd;  // 用于生成随机数种子
    std::mt19937 gen(rd());
    std::uniform_int_distribution<int> dis(0, 255);
    std::stringstream ss;
    for(int i = 0; i < 6; ++i) {
        if(i == 2)
            ss << "-";
        short num = dis(gen);
        ss << std::setw(2) << std::setfill('0') << std::hex << num;
    }
    ss << "-";
    static std::atomic_short idx = 0;
    ss << std::setw(4) << std::setfill('0') << std::hex << idx;
    ++idx;
    return ss.str();
}


std::string verify_code(int n) {
    //生成n位随机验证码
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<int> dis(0, 9); // 生成0-9的随机数
    std::string code;
    for(int i = 0; i < n; ++i) {
        code += std::to_string(dis(gen));
    }
    return code;
}

bool readFile(const std::string& filename, std::string& content) {
    std::ifstream file(filename.data(), std::ios::binary);
    if (!file.is_open()) {
        LOG_ERROR("打开文件失败: {}, {}", filename, std::strerror(errno));
        
        return false;
    }
    // 获取文件大小（当前位置即为文件长度）
    file.seekg(0, std::ios::end);
    std::streamsize size = file.tellg();
    // 回到文件开头
    file.seekg(0, std::ios::beg);
    
    // 预分配string内存
    content.resize(size);
    
    // 一次性读取全部内容
    file.read(&content[0], size);
    if(file.good() == false) {
        LOG_ERROR("读取文件失败: {}", filename);
        file.close();
        return false; // 读取失败
    }
    file.close();
    return true; // 读取失败
}


bool writeFile(const std::string& filename, const std::string& content) {
    std::ofstream file(filename.data(), std::ios::binary | std::ios::trunc);
    if(!file.is_open()) {
        LOG_ERROR("打开文件失败: {}", filename);
        return false;
    }
    file.write(content.data(), content.size());
    if(file.good() == false) {
        LOG_ERROR("写入文件失败: {}", filename);
        file.close();
        return false;
    }
    file.close();
    return true;
}